package com.miplus.ccrm.core.service;

import com.alibaba.fastjson.JSONObject;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.miplus.ccrm.common.CmdResVo;
import com.miplus.ccrm.common.EnumRCode;
import com.miplus.ccrm.common.JPubUtils;
import com.miplus.ccrm.common.ServiceException;
import com.miplus.ccrm.core.controller.vo.file.UploadResVo;
import com.miplus.ccrm.core.service.xsky.XSkyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.io.File;
import java.time.LocalDate;
import java.util.Random;
import java.util.UUID;

@Slf4j
@Service
public class FileService {
    // 本地上传文件的路径
    @Value("${uploadfiles.path}")
    public String uploadPath;
    // 文件上传方式
    @Value("${uploadfiles.type}")
    private String uploadType;

    @Value("${uploadfiles.filetype}")
    private String uploadFileType;

    @Value("${uploadfiles.filesize}")
    private Integer uploadFileSize;
    //
    @Value("${api.url}")
    private String apiUrl;

    @Value("${nginx.url}")
    private String nginxUrl;

    @Value("${ccrm.recfile.url:}")
    private String rec_fileurl;

    @Resource
    private XSkyService ossServiceFile;

    public UploadResVo doUpload(MultipartFile file,Boolean isqmrec) {
        String fileName="";
        if (file.isEmpty()) {
            throw new ServiceException(EnumRCode.FileNull.value, EnumRCode.FileNull.name);
        } else {
            long size = file.getSize(); //校验文件大小
            fileName = file.getOriginalFilename();
            log.info("Upload:fileName={},size={} to {}",fileName,size,uploadType);
            String type = fileName.substring(fileName.lastIndexOf('.') + 1);
            String[] fileType = uploadFileType.split(",");
            if (!Arrays.asList(fileType).contains(type)) {
                throw new ServiceException(EnumRCode.FileTypeErr.value, EnumRCode.FileTypeErr.name);
            } else if (size > 1024 * 1024 * uploadFileSize) {
                throw new ServiceException(EnumRCode.FileSizeOver.value, EnumRCode.FileSizeOver.name);
            }
        }
        UploadResVo resVo=null;
        if(JPubUtils.IsEqual(uploadType,"xsky")){
            resVo = UploadXSky(file);
        }
        else if(isqmrec){
            resVo=UploadRecord(file,fileName);
        }
        else {
            resVo = UploadLocal(file);
        }
        log.info("Upload:fileName={} Done.",fileName);

        return resVo;
    }

    public UploadResVo UploadLocal(MultipartFile file) {
        UploadResVo uploadResVo=new UploadResVo();
        String fileName = file.getOriginalFilename();   //校验文件名
        try {
            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String fileDatePath = LocalDate.now().format(dateFormatter);
            File parentPath = new File(uploadPath + "/"+fileDatePath);
            if (!parentPath.exists()) {
                parentPath.mkdir(); //判断父路径是否存在，不存在就创建出来
            }
            Random r = new Random();
            //String newName = new Date().getTime() + r.nextInt(1000) + fileName.substring(fileName.lastIndexOf("."));
            //2023-08-03
            String newName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf("."));
            log.info("UploadLocal:uploadPath={},apiUrl={},nginxUrl={},newName={}",uploadPath,apiUrl,nginxUrl,newName);
            File newFile = new File(parentPath, newName);
            file.transferTo(newFile);   //复制文件
            String realPath = newFile.getPath();
            String path = "/" + fileDatePath + '/' + newName;

            uploadResVo.setOrifilename(fileName);
            uploadResVo.setFiledir(realPath);
            uploadResVo.setIpaddr(JPubUtils.getLocalIpAddr());
            uploadResVo.setFilename(newName);
            uploadResVo.setApiurl(apiUrl+path);
            if(JPubUtils.IsNotEmpty(nginxUrl)) {
                uploadResVo.setWeburl(nginxUrl + path);
            }
        } catch (Exception e) {
            throw new ServiceException(EnumRCode.FileUploadErr.value,
                    EnumRCode.FileUploadErr.name+":"+e.getMessage()
            );
        }

        return uploadResVo;
    }

    public UploadResVo UploadXSky(MultipartFile file) {
        UploadResVo uploadResVo=new UploadResVo();
        String fileName = file.getOriginalFilename();   //校验文件名
        try {
            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String fileDatePath = LocalDate.now().format(dateFormatter);
            File parentPath = new File(uploadPath + "/"+fileDatePath);
            if (!parentPath.exists()) {
                parentPath.mkdir(); //判断父路径是否存在，不存在就创建出来
            }
            Random r = new Random();
            //String newName = new Date().getTime() + r.nextInt(1000) + fileName.substring(fileName.lastIndexOf("."));
            //2024-08-03
            String newName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf("."));
            log.info("UploadLocal:uploadPath={},apiUrl={},nginxUrl={},newName={}",uploadPath,apiUrl,nginxUrl,newName);
            File newFile = new File(parentPath, newName);
            file.transferTo(newFile);   //复制文件
            String realPath = newFile.getPath();
            //String path = "/" + fileDatePath + '/' + newName;

            String newNamesky =newName;// UUID.randomUUID()+ fileName.substring(fileName.lastIndexOf("."));
            log.info("UploadXSky({}):uploadPath={},apiUrl={},nginxUrl={}",newNamesky,uploadPath,apiUrl,nginxUrl);

            ossServiceFile.UploadFile(newNamesky,newFile);

            uploadResVo.setOrifilename(fileName);
            uploadResVo.setFiledir(realPath);
            uploadResVo.setIpaddr(JPubUtils.getLocalIpAddr());
            uploadResVo.setFilename(newNamesky);
            uploadResVo.setApiurl(apiUrl);
            uploadResVo.setWeburl(newNamesky);

            DeleteTemFile(newFile);

            log.info("UploadXSky({}):Done",newNamesky);

        } catch (Exception e) {
            log.error("UploadXsky.Err:",e);
            throw new ServiceException(EnumRCode.FileUploadErr.value,
                    EnumRCode.FileUploadErr.name+":"+e.getMessage()
            );
        }
        return uploadResVo;
    }

    public UploadResVo UploadRecord(MultipartFile file,String fileName)
    {
        String urlbody=rec_fileurl;
        if(!urlbody.endsWith("/")) urlbody=urlbody+"/";
        urlbody=urlbody+"file/uploadRecord";
        try {
            log.info("UploadRecord:{} To {}",fileName,urlbody);
            //.header("content-type", "multipart/form-data") 不能加，否则接收端会失败
            HttpResponse<JsonNode> response = Unirest.post(urlbody)
                    .field("file", file.getInputStream(), fileName).asJson();
            int status = response.getStatus();
            if (status == 200) {
                JsonNode responseBody = response.getBody();
                log.info("UploadRecord.Response:{}", responseBody);

                Integer code = responseBody.getObject().getInt("code");
                String message = responseBody.getObject().get("message").toString();
                if (code == 200) {
                    UploadResVo resVo = new UploadResVo();
                    org.json.JSONObject pdata = responseBody.getObject().getJSONObject("data");
                    resVo.setFilename(pdata.getString("filename"));
                    resVo.setFiledir(pdata.getString("filepath"));
                    resVo.setIpaddr(pdata.getString("ipaddr"));
                    resVo.setRecspan(pdata.getInt("recspan"));
                    resVo.setFilekey(pdata.getString("filekey"));
                    resVo.setOrifilename(fileName);
                    return resVo;
                } else {
                    throw new ServiceException(EnumRCode.FileUploadErr.value, message);
                }
            }
            else{
                log.info("UploadRecord.Fail:{}", response.getBody());
                throw new ServiceException(EnumRCode.FileUploadErr.value, "UploadFail:"+response.getStatus());
            }
        }
        catch (Exception e){
            log.warn("UploadRecord.Err:{}",e.getMessage());
            throw new ServiceException(EnumRCode.FileUploadErr.value,
                    EnumRCode.FileUploadErr.name+":"+e.getMessage()
            );
        }
    }

    public CmdResVo DownloadFile(String skyid, HttpServletResponse response)
    {
        try {
            ossServiceFile.DownloadFile(skyid,response);
            return new CmdResVo(1,skyid);

        } catch (Exception e) {
            log.error("DownloadFile.Err:",e);
            throw new ServiceException(EnumRCode.FileDownloadErr.value,
                    EnumRCode.FileDownloadErr.name+":"+e.getMessage()
            );
        }
    }

    //2024-08-03
    private void DeleteTemFile(File file)
    {
        try{
            log.info("DeleteTemFile:{}",file.getName());

            file.delete();
        }
        catch (Exception e){
            log.error("DeleteTemFile.Err:",e);
        }
    }
}
